package blacklist

import (
	"context"
	"dfx_cmdb/cmdb-agent/global"
	"dfx_cmdb/cmdb-agent/types"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"

	"gitee.com/daofeixian/dfx_golang_toolset/utils"
	"github.com/zeromicro/go-zero/core/logc"
)

func GetServerBlackListApiIpListMap(ctx context.Context, t string) (map[string]types.StringList, error) {
	return getServerBlackListApiIpListMap(ctx, t)
}

func getServerBlackListApiIpListMap(ctx context.Context, t string) (map[string]types.StringList, error) {
	serverUrl := fmt.Sprintf("%s/%s", global.Svc.Config.ServiceAddr, global.CMDB_BLACKLIST_GETBLACKLIST_URI)
	u, err := url.Parse(serverUrl)
	if err != nil {
		logc.Errorf(ctx, "解析服务地址失败: %v", err)
		return nil, err
	}
	logc.Debug(ctx, serverUrl)
	q := u.Query()
	q.Set("type", t)
	u.RawQuery = q.Encode()

	reqJson, err := utils.HttpDo(ctx, u.String(), "GET", nil, nil)
	if err != nil {
		logc.Errorf(ctx, "请求服务失败，错误信息: %v", err)
		return nil, err
	}

	if len(reqJson) == 0 {
		logc.Errorf(ctx, "服务返回数据为空")
		return nil, errors.New("服务返回数据为空")
	}

	resp := types.PublicResponse[types.BlacklistData]{}
	err = json.Unmarshal(reqJson, &resp)
	if err != nil {
		logc.Errorf(ctx, "解析服务返回数据失败，错误信息: %v", err)
		return nil, err
	}

	return resp.Data.Blacklist, nil
}

type AgentBlacklistInter interface {
	EnableBlacklist(ctx context.Context) error
	DisableBlacklist(ctx context.Context) error
}

// GetBlacklistHandler 根据黑名单模式名称返回对应的处理器实例
func GetBlacklistHandler(mode string) (AgentBlacklistInter, error) {
	switch mode {
	case global.CMDB_BLACKLIST_HAPROXY_NAME:
		return NewHaproxyBlackList(), nil
	case global.CMDB_BLACKLIST_EBPF_NAME:
		return NewEbpfBlackList(), nil
	case global.CMDB_BLACKLIST_OPENRESTY_NAME:
		return NewOpenrestyBlackList(), nil
	default:
		return nil, fmt.Errorf("不支持的黑名单模式: %s", mode)
	}
}

func InitCron(ctx context.Context) (bool, error) {
	// 定义黑名单模式列表
	modes := global.BlacklistTypeModes

	// 查找启用的黑名单模式
	for _, mode := range modes {
		value, ok := global.BlacklistCronStatusMap.Load(mode)
		if !ok {
			return false, fmt.Errorf("未找到 %s 的黑名单状态", mode)
		}

		enabled, isBool := value.(bool)
		if !isBool {
			return false, fmt.Errorf("%s 的黑名单状态类型错误", mode)
		}

		if enabled {
			// 获取对应的黑名单处理器
			blacklistHandler, err := GetBlacklistHandler(mode)
			if err != nil {
				return false, fmt.Errorf("获取 %s 黑名单处理器失败: %v", mode, err)
			}

			// 找到启用的模式，创建定时任务
			global.Svc.CronJobId, err = global.Svc.Cron.AddFunc(global.Svc.Config.Function.Crontab, func() {
				// 执行黑名单更新逻辑
				err := blacklistHandler.EnableBlacklist(ctx)
				if err != nil {
					logc.Errorf(ctx, "执行 %s 黑名单定时任务失败，错误信息: %v", mode, err)
					return
				}
				logc.Infof(ctx, "执行 %s 黑名单定时任务成功", mode)
			})
			if err != nil {
				return false, fmt.Errorf("启动 %s 的黑名单任务失败，错误信息: %v", mode, err)
			}
			logc.Infof(ctx, "成功启动 %s 黑名单定时任务，Cron 表达式: %s", mode, global.Svc.Config.Function.Crontab)
			return true, nil
		}
	}

	return false, nil
}
